#include "book.h"
#include "libc.h"
#define  BOOK_01  "1:/TXT/大学.txt"
#include "key.h"
void delay_ms(uint32_t wMs);

#define BOOK_PATH_FOLDER_ONLY "TXT/"
#define BOOK_PATH_FOLDER "1:/TXT"
#define BOOK_PATH_NEWFILE_TXT "TXT/newfile.txt"

#define READ_COUNT_NUM 128
#define PAGE_LINES 4
#define PAGE_LINE_NUM 17

typedef struct book{
    int book_num;
    int book_num_current;
    int book_lseek_current;
    int book_read_count_num;
    int book_size;
    int16_t iX;
    int16_t iY;
    int16_t iWidth;
    int16_t iHeight;
    
    char page_line_data[PAGE_LINES][PAGE_LINE_NUM];
    char book_path[256];
    char book_key;
    char fount_size;
}book_t;

static book_t my_book;

void my_book_init(){
    my_book.book_num_current = 0;  
    my_book.book_key = 0;
    my_book.book_lseek_current = 0;
    my_book.book_read_count_num = READ_COUNT_NUM;
    my_book.iX = 0;
    my_book.iY = 0;
    my_book.iWidth = 128-16;
    my_book.iHeight = 64;
    my_book.fount_size = 8;
}
void page_line_data_init(){
    for(int i = 0; i < PAGE_LINES; i++){
        for(int j = 0; j < PAGE_LINE_NUM; j++){
            my_book.page_line_data[i][j] = ' ';
        }
        my_book.page_line_data[i][PAGE_LINE_NUM-1] = 0;
    }
}

void my_book_init1(){
    FRESULT res;  // FatFs返回结果
    DIR dir;      // 目录对象
    FILINFO fno;  // 文件信息结构体
    
    char temp_buff[10][128];
    char i = 0;
    // 尝试打开目录
    res = f_opendir(&dir,  BOOK_PATH_FOLDER);
    if (res != FR_OK) {
        //printf("打开目录失败，错误码：%d\n", res);
        return;
    }
    
    // 循环读取目录项
    while (1) {
        res = f_readdir(&dir, &fno);  // 读取一个目录项
        if (res != FR_OK || fno.fname[0] == 0) break;  // 出错或到达目录尾部时退出循环
        if (fno.fattrib & AM_DIR) {
            // 这是一个目录
            //draw_string(0,0,16,fno.fname);
        }else{
            // 这是一个文件，尝试打开
            
            
            strcpy(&temp_buff[i][0],fno.fname);
            i++;
        }

    }
    f_closedir(&dir);  // 关闭目录
    
    FIL file;  // 文件对象
    UINT bw;
    // 以写入模式打开文件，如果不存在则创建
    if (f_open(&file, BOOK_PATH_NEWFILE_TXT, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) {
        //error("File open failed");
        return;
    }
    
   
    for(int j = 0; j < i; j++){
        res = f_lseek(&file, j*128);
        if (res == FR_OK) {
            //const char *data = "追加的数据\n";
            res = f_write(&file, &temp_buff[j][0], 128, &bw); // 写入数据
            f_sync(&file); // 刷新数据
        }
    }
    // 关闭文件
    if (f_close(&file) != FR_OK) {
        //error("File close failed");
        return;
    }
    
    //=========================
    char out_buff[128];
    uint32_t rd_len;
    res = f_open(&file,  BOOK_PATH_NEWFILE_TXT, FA_READ);
    if (res == FR_OK) {
        //printf("成功打开文件：%s\n", fno.fname);
        // 这里可以进行文件操作，例如读取内容等
        for(int j = 0; j < i; j++){
            res = f_lseek(&file, j*128);
            if (res == FR_OK) {
                res = f_read(&file, out_buff, 128, &rd_len);
                //draw_string(0,16,16,out_buff);
            }
        }
        
        f_close(&file) ;

    }
   
}

FSIZE_t get_folder_size(const char* path);





void lcd_show_folder(){//显示目录
    FIL file;  // 文件对象
    FRESULT res;  // FatFs返回结果
    FILINFO fno;  // 文件信息结构体
    //FSIZE_t  size = 0;
    int num = 0;
    char out_buff[128];
    uint32_t rd_len;
    
    res = f_open(&file,  BOOK_PATH_NEWFILE_TXT, FA_READ);
    if (res == FR_OK) {
        // 获取文件状态
        res = f_stat(BOOK_PATH_NEWFILE_TXT, &fno);
        if (res == FR_OK) {
            // 如果成功，将文件大小存储在提供的指针中
            //size = fno.fsize;
            //num = fno.fsize / 128;
            my_book.book_num = fno.fsize / 128;
        }
        for(int i = 0; i < my_book.book_num; i++){
            res = f_lseek(&file, i*128);
            if (res == FR_OK) {
                res = f_read(&file, out_buff, 128, &rd_len);
                draw_string(16,16*i,16,out_buff);
            }
        }
        
        f_close(&file) ;
    }

}
int get_book_num(){
    static char i = 0;
    i++;
    if( i >= my_book.book_num){
        i =0;
    }
    return i;
}
void read_book(int num){
    FIL file;  // 文件对象
    FRESULT res;  // FatFs返回结果
    FILINFO fno;  // 文件信息结构体
    char out_buff[128];
    uint32_t rd_len;
    
    res = f_open(&file,  BOOK_PATH_NEWFILE_TXT, FA_READ);
    if (res == FR_OK) {
        res = f_lseek(&file, num*128);
        if (res == FR_OK) {
            res = f_read(&file, out_buff, 128, &rd_len);
            //draw_string(0,16*i,16,out_buff);
            if(res!=FR_OK )
            {
                return;            
            }
            
            strcpy(&my_book.book_path[0],BOOK_PATH_FOLDER_ONLY);
            strcpy(&my_book.book_path[4],out_buff);
        }
        f_close(&file) ;
    }
    
    res = f_open(&file,my_book.book_path, FA_READ);
    if (res == FR_OK) {
       
        res = f_read(&file, out_buff, 128, &rd_len);
        if(res!=FR_OK ){
            return;            
        }
        char show_str[128];
        out_buff[127] = 0;
        
        strcpy(show_str,&out_buff[0]);
        show_str[16] = 0;
        draw_string(0,16*0,16,show_str);
        
        strcpy(show_str,&out_buff[16]);
        show_str[16] = 0;
        draw_string(0,16*1,16,show_str);
        
        strcpy(show_str,&out_buff[32]);
        show_str[16] = 0;
        draw_string(0,16*2,16,show_str);
        
        strcpy(show_str,&out_buff[48]);
        show_str[16] = 0;
        draw_string(0,16*3,16,show_str);
        
        
        
        
        f_close(&file);
    }

}

void my_read_book_path(){
    FIL file;  // 文件对象
    FRESULT res;  // FatFs返回结果
    FILINFO fno;  // 文件信息结构体
    char out_buff[128];
    uint32_t rd_len;
    res = f_open(&file,  BOOK_PATH_NEWFILE_TXT, FA_READ);
    if (res == FR_OK) {
        res = f_lseek(&file, my_book.book_num_current*128);
        if (res == FR_OK) {
            res = f_read(&file, out_buff, 128, &rd_len);
            //draw_string(0,16*i,16,out_buff);
            if(res!=FR_OK )
            {
                return;            
            }
            
            strcpy(&my_book.book_path[0],BOOK_PATH_FOLDER_ONLY);
            strcpy(&my_book.book_path[4],out_buff);
        }
        f_close(&file) ;
    }
    // 获取文件状态
    res = f_stat(my_book.book_path, &fno);
    my_book.book_size = fno.fsize ;
    
}

void my_read_book_data(){
    FIL file;  // 文件对象
    FRESULT res;  // FatFs返回结果
    uint32_t rd_len;
    char out_buff[READ_COUNT_NUM];
    
    res = f_open(&file,my_book.book_path, FA_READ);
    if (res == FR_OK) {
        res = f_lseek(&file, my_book.book_lseek_current);
        if(res!=FR_OK ){
            return;            
        }
        res = f_read(&file, out_buff, my_book.book_read_count_num, &rd_len);
        if(res!=FR_OK ){
            return;            
        }
        f_close(&file);
    }
    page_line_data_init();
    uint16_t line = 0;
    uint16_t line_nums  = 0;
    uint16_t data_nums = 0;
    while(1){
        if(out_buff[data_nums] < 0x80){
            if((line_nums * my_book.fount_size) >= (my_book.iWidth)){
                line++;
                line_nums  = 0;
                if(line >= PAGE_LINES){
                    break;
                }    
            }
            my_book.page_line_data[line][line_nums] = out_buff[data_nums];
            data_nums++;
            line_nums++;
            
        }else{
            if((line_nums * my_book.fount_size) >= (my_book.iWidth - my_book.fount_size)){
                line++;
                line_nums  = 0;
                if(line >= PAGE_LINES){
                    break;
                }    
            }
            my_book.page_line_data[line][line_nums] = out_buff[data_nums];
            my_book.page_line_data[line][line_nums+1] = out_buff[data_nums+1];
            data_nums+=2;
            line_nums+=2;
        }
        
    }
    my_book.book_lseek_current += data_nums;
    draw_string(0,16*0,16,&my_book.page_line_data[0][0]);
    draw_string(0,16*1,16,&my_book.page_line_data[1][0]);
    draw_string(0,16*2,16,&my_book.page_line_data[2][0]);
    draw_string(0,16*3,16,&my_book.page_line_data[3][0]);
    
    //OLED_DrawBitmap(int16_t iX, int16_t iY, int16_t iWidth, int16_t iHeight, const uint8_t *pchBuffer);
    draw_line_list(my_book.book_lseek_current*100 /my_book.book_size);
    
}

void my_read_book(){    
    static char book_state = 0;

    switch(book_state){
        case 0:
            my_read_book_path();
            book_state = 1;
        //break;
        case 1:
            my_read_book_data();
            book_state = 2;
        break;
        case 2:
            if(my_book.book_key == 1){
                my_book.book_key = 0; 
                book_state = 1;
            }
            if(my_book.book_key == 2){
                //my_book.book_key = 0; 
                book_state = 0;
            }
        break;
    
    }
    
    
}

void book_task(){
    static char state = 0;
    switch(state){
        case 0: 
            my_book_init();
            state = 1;
        //break;
        case 1:
            OLED_Clear(); 
            lcd_show_folder();   
            state = 2;
        break;
        case 2:
            if(my_book.book_key == 1){
                my_book.book_key = 0;
                my_book.book_num_current++;
                my_book.book_num_current = my_book.book_num_current % my_book.book_num;
            }
            if(my_book.book_key == 2){
                my_book.book_key = 0;
                OLED_Clear(); 
                //read_book(my_book.book_num_current);
                state = 3;
                break;
            }
            for(int i = 0; i < 4; i++){
                draw_char_EN(0,16*i,16,' ');
            }
            draw_char_EN(0,16*my_book.book_num_current,16,'>');
        break;
        case 3:
            my_read_book();
            if(my_book.book_key == 2){
                //my_book.book_key = 0;
                state = 0;
                break;
            }
        break;
    }
}
void  book_test(void){
    char key_num = 0;
    while(1){
        
        key_num = key_scan();
        if(key_num){
            my_book.book_key = key_num;
        }
        book_task();
        if(my_book.book_key == 2){
            my_book.book_key = 0;
            main_exit();
            break;
        }
        delay_ms(10);
    }
    
}

//===================================
void my_book_init2(){
    FRESULT res;  // FatFs返回结果
    DIR dir;      // 目录对象
    FILINFO fno;  // 文件信息结构体
    FSIZE_t  size = 0;
    char key_num = 0;
    int book_num = 0;
    
    //size = get_folder_size( "1:/TXT");
    lcd_show_folder();
    while(1){
        key_num = key_scan();
        if(key_num){
            if(key_num == 1){
                //draw_string(0,16,16,"1");
                book_num = get_book_num();
            }
            if(key_num == 2){
                //draw_string(0,16,16,"2");
                read_book(book_num);
            }
            
            //draw_string(0,16,16,"3");
            draw_char_EN(0,0,16,book_num+'0');
            
        }
        delay_ms(10);
    }
    
 
}
int read_files_name(){
    FRESULT res;  // FatFs返回结果
    DIR dir;      // 目录对象
    FILINFO fno;  // 文件信息结构体
    int file_count = 0;  // 文件计数器
    const char* path =  BOOK_PATH_FOLDER;
    // 尝试打开目录
    res = f_opendir(&dir, path);
    if (res == FR_OK) {
        // 循环读取目录项
        while (1) {
            res = f_readdir(&dir, &fno);  // 读取一个目录项
            if (res != FR_OK || fno.fname[0] == 0) break;  // 出错或到达目录尾部时退出循环
            if (!(fno.fattrib & AM_DIR)) {  // 忽略子目录，只计算文件
                file_count++;  // 文件计数加一
            }
        }
        f_closedir(&dir);  // 关闭目录
    } else {
        // 打开目录失败，处理错误
        return -1;  // 返回错误代码
    }
    return file_count;  // 返回文件数量
}

// 打开目录中的每个文件并打印其名称
void open_files_in_directory(const char* path) {
    FRESULT res;  // FatFs返回结果
    DIR dir;      // 目录对象
    FILINFO fno;  // 文件信息结构体

    // 尝试打开目录
    res = f_opendir(&dir, path);
    if (res != FR_OK) {
        //printf("打开目录失败，错误码：%d\n", res);
        return;
    }

    // 循环读取目录项
    while (1) {
        res = f_readdir(&dir, &fno);  // 读取一个目录项
        if (res != FR_OK || fno.fname[0] == 0) break;  // 出错或到达目录尾部时退出循环

        if (fno.fattrib & AM_DIR) {
            // 这是一个目录
            draw_string(0,0,16,fno.fname);
            /*
            FIL fil;   // 文件对象
            char *write_data = "new";
            UINT bw;   // 写入的字节数
            // 以写入模式打开文件，如果不存在则创建
            if (f_open(&fil, "TXT/newfile.txt", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) {
                //error("File open failed");
            }

            // 写入数据
            if (f_write(&fil, write_data, sizeof(write_data), &bw) != FR_OK || bw != sizeof(write_data)) {
                //error("File write failed");
            }
            // 关闭文件
            if (f_close(&fil) != FR_OK) {
                //error("File close failed");
            }
            */
            //printf("目录：%s\n", fno.fname);
        } else {
            // 这是一个文件，尝试打开
            FIL file;  // 文件对象
            //res = f_open(&file, fno.fname, FA_READ);//"1:/TXT/大学.txt"
            char book_name[100]="TXT/";
            strcpy(&book_name[4],fno.fname);
            res = f_open(&file, book_name, FA_READ);//"1:/TXT/大学.txt"
            if (res == FR_OK) {
                //printf("成功打开文件：%s\n", fno.fname);
                // 这里可以进行文件操作，例如读取内容等
                int len;
                uint32_t rd_len;
                uint8_t out_buff[50];
                len = 16;
                res = f_read(&file, out_buff, len, &rd_len);
                
                if(res!=FR_OK || rd_len!=len)
                {
                        
                }
                out_buff[16] = 0;
                
                draw_string(0,0,16,fno.fname);
                draw_string(0,16,16,out_buff);
                
                f_close(&file);  // 操作完成后关闭文件
                //break;
            } else {
                //printf("打开文件失败，错误码：%d\n", res);
            }
        }
    }

    f_closedir(&dir);  // 关闭目录
}
void  book_test2(){
    const char *fname;
    FIL fil;
    fname = BOOK_01;
    int i, ret;	 
    int len;
    uint32_t rd_len;
    uint8_t out_buff[50];
    
    
    
    //len = read_files_name();
    
    open_files_in_directory( "1:/TXT");
    return;
    
    if(f_open(&fil, fname, FA_READ) != FR_OK){
        return ;
    }
    
    //ret = f_lseek(fil, foffset);
    //if(ret != FR_OK)
	//{

	//}
    len = 16;
    ret = f_read(&fil, out_buff, len, &rd_len);
    
    if(ret!=FR_OK || rd_len!=len)
	{
	    	
	}
    out_buff[16] = 0;
    draw_string(0,16,16,out_buff);
    
    f_close(&fil);
        
}

FSIZE_t get_folder_size(const char* path) {
    DIR dir;
    FILINFO fno;
    FSIZE_t size = 0;
    FRESULT res;

    // 打开目录
    res = f_opendir(&dir, path);
    if (res != FR_OK) return 0;

    // 遍历目录
    while (1) {
        res = f_readdir(&dir, &fno);
        if (res != FR_OK || fno.fname[0] == 0) break;
        if (fno.fattrib & AM_DIR) {
            // 如果是子文件夹，递归调用 get_folder_size
            char subpath[256];
            sprintf(subpath, "%s/%s", path, fno.fname);
            // 如果不是根目录，并且文件夹不是隐藏的，则递归计算大小
            if (strcmp(fno.fname, ".") && strcmp(fno.fname, "..")) {
                size += get_folder_size(subpath);
            }
        } else {
            // 如果文件不是隐藏的，则累加文件大小
            if (!(fno.fattrib & AM_HID)) {
                size += fno.fsize;
            }
        }
    }
    f_closedir(&dir);
    return size;
}



//=============================
void zj_data(){
    FRESULT res;
    FIL file;
    UINT bw;

    // 打开文件以追加写入
    res = f_open(&file, "0:/example.txt", FA_OPEN_APPEND | FA_WRITE);
    if (res == FR_OK) {
        const char *data = "追加的数据\n";
        res = f_write(&file, data, strlen(data), &bw); // 写入数据
        f_close(&file); // 关闭文件
    }
}

void zj_data2(){
    FRESULT res;
    FIL file;
    UINT bw;

    // 打开文件以写入
    res = f_open(&file, "0:/example.txt", FA_OPEN_EXISTING | FA_WRITE);
    if (res == FR_OK) {
        // 移动文件指针到文件末尾
        res = f_lseek(&file, f_size(&file));
        if (res == FR_OK) {
            const char *data = "追加的数据\n";
            res = f_write(&file, data, strlen(data), &bw); // 写入数据
        }
        f_close(&file); // 关闭文件
    }
}
void zj_data3(){
    FRESULT res;
    FIL file;
    UINT bw;
    while (1) {
        // 打开文件
        res = f_open(&file, "0:/example.txt", FA_OPEN_ALWAYS | FA_WRITE);
        if (res == FR_OK) {
            const char *data = "持续写入的数据\n";
            res = f_write(&file, data, strlen(data), &bw);
            f_sync(&file); // 刷新数据
            f_close(&file); // 关闭文件
        }
    }
}
